﻿using System;
using System.Drawing.Drawing2D;
using System.Drawing;

namespace barcodes
{

    class BarcodeRenderer
    {
        private ImageSettings imgSettings_;
        public BarcodeRenderer()
        {
            imgSettings_ = new ImageSettings();   
        }
        /// <summary>
        /// Возвращает Image с изображением штрихкода в формате EAN-13
        /// </summary>
        /// <param name="input">Строка для кодирования</param>
        /// <param name="imageWidth">Высота изображения</param>
        /// <param name="imageHeigth">Ширина изображения</param>
        /// <param name="inverted">true, если требуется инвертированное изображение </param>
        /// <returns>Изображение</returns>
        public Image GetImage(String input, int imageWidth, int imageHeigth, bool inverted)
        {
            //init
            Converter conv = new Converter();
            string code = String.Empty;

            try
            {
                code = conv.GetBarcodePres(input);
            }
            catch(BadInputException ex)
            {
                throw ex;
            }

            //Подготовка изображения
            Image img = (Image)new Bitmap(imageWidth, imageHeigth);
            Graphics grfx = Graphics.FromImage(img);
            grfx.CompositingMode = CompositingMode.SourceOver;
            grfx.SmoothingMode = SmoothingMode.Default;

            
            Brush backgroundBrush = inverted ?  Brushes.Black: Brushes.White;
            Pen p = new Pen(inverted?Color.White : Color.Black, 1);
            Brush barBrush = inverted ? Brushes.White : Brushes.Black ;

            Font font = new Font(FontFamily.GenericSansSerif, 10);

            FillBackground(img, grfx, backgroundBrush);
            
            

            int yPos = 70;  //координаты цифровой строки
            int xPos = 58;
            int step = 14;

            Brush digitBrush = inverted ? Brushes.White : Brushes.Black;

            grfx.DrawString(input[0].ToString(), font, digitBrush, 38, yPos);    //Первая цифра
            for (int indx = 1; indx != input.Length; indx++)
            {
                grfx.DrawString(input[indx].ToString(), font, digitBrush, xPos, yPos);
                if (indx == 6)
                    xPos += 8;
                xPos += step;
            }

            int cdPos = 220;
            grfx.DrawString(conv.GetControlDigit().ToString(), font, digitBrush, cdPos, 70);
            grfx.DrawString(">", font, digitBrush, cdPos + 20, 70);

            DrawBarcode(code,  grfx, barBrush);
            grfx.Dispose();

            return img;
        }
        /// <summary>
        /// Закрашивает фон картинки заданным цветом.
        /// </summary>
        /// <param name="img">Изображение</param>
        /// <param name="grfx">Объект System.DrowingGraphics</param>
        /// <param name="brsh">Кисть</param>
        private static void FillBackground(Image img, Graphics grfx, Brush brsh)
        {
            Rectangle rect = new Rectangle();
            rect.Width = img.Width;
            rect.Height = img.Height;
            grfx.FillRectangle(brsh, rect);
        }
        
        /// <summary>
        /// Отрисовка штрих-кода (без цифр)
        /// </summary>
        /// <param name="code"></param>
        /// <param name="grfx">Оъект System.Drawing.Graphix</param>
        /// <param name="br">Кисть</param>
        private void DrawBarcode(String code, Graphics grfx, Brush br)
        {
            Int32 linePos   = 50;
            Int32 dy = 20;

            for (int indx = 0; indx != code.Length; indx++)
            {
                if (code[indx] == '1')
                {
                    // 2, 44, 50 - позиции калибровочных штрихов
                    if ((indx <= 2) || ((indx > 44) && (indx < 50)) || ((indx > code.Length - 4) && (indx < code.Length)))
                    {
                        grfx.FillRectangle(br, linePos, dy, imgSettings_.BarWidth, imgSettings_.BarCodeCallHeight);
                    }
                    else
                        grfx.FillRectangle(br, linePos, dy, imgSettings_.BarWidth, imgSettings_.BarCodeHeight);
                }
                linePos += imgSettings_.BarWidth;
            }
 
        }

        //public Image Paint()
        //{
        //    top = settings.TopMargin;


        //    Graphics g = Graphics.FromImage(new Bitmap(1, 1));


        //    int width = (3 + 6 * 7 + 5 + 6 * 7 + 3) * settings.BarWidth + settings.LeftMargin + settings.RightMargin + (int)g.MeasureString(code[0].ToString(), settings.Font).Width;
        //    int height = settings.BarCodeHeight;


        //    if (title != null)
        //    {
        //        int h = (int)g.MeasureString(title, settings.Font).Height;
        //        height += h;
        //        top += h;
        //    }


        //    Bitmap bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
        //    g = Graphics.FromImage(bmp);


        //    int left = settings.LeftMargin;


        //    //LEFT GUARD
        //    left = DrawLeftGuard(settings, g, code[0].ToString(), left);


        //    //LEFT GROUP
        //    int first = int.Parse(code[0].ToString());
        //    Parity par = parity[first];
        //    string digit = code[1].ToString();
        //    left = Draw(settings, g, left, digit, codes[int.Parse(digit)].LhOdd); //Odd

        //    for (int i = 2; i <= 6; i++)
        //    {
        //        digit = code[i].ToString();
        //        Pattern p = codes[int.Parse(digit)];
        //        left = Draw(settings, g, left, digit, (par.IsOdd(i - 2) ? p.LhOdd : p.LhEven));
        //    }


        //    //MIDDLE GUARD
        //    left = DrawCenterGuard(settings, g, left);


        //    //RIGHT GROUP
        //    for (int i = 7; i <= 12; i++)
        //    {
        //        digit = code[i].ToString();
        //        Pattern p = codes[int.Parse(digit)];
        //        left = Draw(settings, g, left, digit, p.Rh);
        //    }


        //    //RIGHT GUARD
        //    left = DrawRightGuard(settings, g, left);


        //    return bmp;
        //}


        //private static Pen pen = new Pen(Color.Black);
        //private static Brush brush = Brushes.Black;


        //private int Draw(ImageSettings settings, Graphics g, int left, string digit, string s)
        //{
        //    int h = (int)(settings.BarCodeHeight * 0.8);
        //    g.DrawString(digit, settings.Font, brush, left, h + top);


        //    foreach (char c in s)
        //    {
        //        if (c == '1')
        //            g.FillRectangle(brush, left, top, settings.BarWidth, h);


        //        left += settings.BarWidth;
        //    }


        //    return left;
        //}


        //private int DrawLeftGuard(ImageSettings settings, Graphics g, string digit, int left)
        //{
        //    int h = (int)(settings.BarCodeHeight * 0.8);
        //    g.DrawString(digit, settings.Font, brush, left, h + top);
        //    left += (int)g.MeasureString(digit, settings.Font).Width;


        //    //TITLE
        //    if (title != null)
        //        g.DrawString(title, settings.Font, brush, left, settings.TopMargin);


        //    g.FillRectangle(brush, left, top, settings.BarWidth, settings.BarCodeHeight); //1
        //    left += settings.BarWidth;


        //    left += settings.BarWidth;                                                                   //0


        //    g.FillRectangle(brush, left, top, settings.BarWidth, settings.BarCodeHeight); //1
        //    left += settings.BarWidth;


        //    return left;
        //}


        //private int DrawRightGuard(ImageSettings settings, Graphics g, int left)
        //{
        //    g.FillRectangle(brush, left, top, settings.BarWidth, settings.BarCodeHeight); //1
        //    left += settings.BarWidth;


        //    left += settings.BarWidth;                                                                   //0


        //    g.FillRectangle(brush, left, top, settings.BarWidth, settings.BarCodeHeight); //1
        //    left += settings.BarWidth;


        //    return left;
        //}


        //private int DrawCenterGuard(ImageSettings settings, Graphics g, int left)
        //{
        //    left += settings.BarWidth;                                                                   //0


        //    g.FillRectangle(brush, left, top, settings.BarWidth, settings.BarCodeHeight); //1
        //    left += settings.BarWidth;


        //    left += settings.BarWidth;                                                                   //0


        //    g.FillRectangle(brush, left, top, settings.BarWidth, settings.BarCodeHeight); //1
        //    left += settings.BarWidth;


        //    left += settings.BarWidth;                                                                   //0


        //    return left;
        //}

    }  
  
}
